﻿#include <iostream>
#include <SYSSELEC.HPP>
#include <GUID.HPP>
#include <CXXLCOMPOSITE.HPP>
#include <CENTRALIZEDMGR.HPP>
#include <TXTSTORAGE.HPP>
#include <MEMSTORAGE.HPP>
//#include <PRESERVE2.HPP>
//#include <PRESERVECOMMON.HPP>

using namespace CxxlMan;

// 動態元件檔控管介面
class DllFileContext;

// Proxy Patterns
class CSpirit_Surrogate;

// Proxy Patterns
class CSpirit_Preserve2;


// 代替 Preserve2 元件放入容器中
class Preserve2Cradle;

// 要放入 Uterus 的結構
struct Preserve2Baby:virtual public cxxlObject
{
  UNICODE_String InterfaceID;
  UNICODE_String ObjID;
  UNICODE_String Group;
  Smart_Ptr<cxxlPreserve2> Preserve2_Ptr;
  Smart_Ptr<DllFileContext> DllFileContext_Ptr;

  Preserve2Baby(const UNICODE_String InterfaceID_Arg, const UNICODE_String ObjID_Arg, const UNICODE_String Group_Arg,
    const Smart_Ptr<cxxlPreserve2> &Preserve2_Arg, const Smart_Ptr<DllFileContext> &DllFileContext_Arg)
    :cxxlObject(Spirit_Easy), InterfaceID(InterfaceID_Arg), ObjID(ObjID_Arg), Group(Group_Arg), Preserve2_Ptr(Preserve2_Arg), DllFileContext_Ptr(DllFileContext_Arg)
  {
  }

};

// 使用 CentralizedMgr 的再生功能時，暫存新建的 Preserve2 物件
class Uterus:virtual public cxxlObject
{
  class Preserve2Baby_AvlTree:public cxxlAVL_Tree<Preserve2Baby, UNICODE_String, true>
  {
    bool cxxlFASTCALL isLeftAt(UNICODE_String O_Key,UNICODE_String addKey) const
    {
      return O_Key < addKey;
    }

    bool cxxlFASTCALL isEqual(UNICODE_String O_Key,UNICODE_String findKey)  const
    {
      return O_Key == findKey;
    }

  public:
    Preserve2Baby_AvlTree(ISpirit *spirit=Spirit_Easy)
      :cxxlObject(spirit),cxxlAVL_Tree<Preserve2Baby, UNICODE_String, true>(spirit)
    {

    }

  };

  Smart_Ptr<cxxlList<Preserve2Baby> > Preserve2Baby_List;
  Smart_Ptr<Preserve2Baby_AvlTree> Preserve2Baby_Tree;
public:
  // Constructor
  Uterus()
    :cxxlObject(Spirit_Easy),
     Preserve2Baby_List(new cxxlList<Preserve2Baby>,this),
     Preserve2Baby_Tree(new Preserve2Baby_AvlTree,this)
  {
  }

  // Destructor
  virtual ~Uterus()
  {
  }

  void cxxlFASTCALL Add(const Smart_Ptr<Preserve2Baby> &Preserve2Baby_Arg, const UNICODE_String &ObjID_Key)
  {
    if(Preserve2Baby_Tree->Add(Preserve2Baby_Arg, ObjID_Key) == true)
      Preserve2Baby_List->Push_Back(Preserve2Baby_Arg);
  }

  Smart_Ptr<Preserve2Baby> cxxlFASTCALL Get(const UNICODE_String &ObjID_Key)
  {
    return Preserve2Baby_Tree->GetObj(ObjID_Key);
  }

  Smart_Ptr<cxxlList<Preserve2Baby> > cxxlFASTCALL Get_Preserve2Baby_List()
  {
    return Preserve2Baby_List;
  }

};

class CentralizedMgr:virtual public cxxlObject, public ICentralizedMgr
{
  // 包裹 Preserve2Cradle 物件，採用 UNICODE_String 為 key，key 值不可重複
  class Preserve2CradleTree:public cxxlAVL_Tree<Preserve2Cradle,UNICODE_String,true>
  {
    // 排序檢測，延伸類別須實作此函數
    // 要讓 O_Key 鍵值所代表的物件排在 左 回答 true，否則 false
    bool cxxlFASTCALL isLeftAt(UNICODE_String O_Key,UNICODE_String addKey) const
    {
      return O_Key <= addKey;
    }

    // 這函數用來決定在容器中 O_Key 鍵值所代表的物件，是不是 findKey 所要尋找的
    // 是 回答 true，否則 false，延伸類別須實作此函數
    bool cxxlFASTCALL isEqual(UNICODE_String O_Key,UNICODE_String findKey)  const
    {
      return O_Key == findKey;
    }

  public:
    Preserve2CradleTree()  // Constructor
      :cxxlObject(Spirit_Easy)
    {
    }
  }_Preserve2CradleSet;

  // 包裹 DllFileContext 物件，採用 UNICODE_String 為 key，key 值不可重複
  class DllFileContextTree:public cxxlAVL_Tree<DllFileContext,UNICODE_String,true>
  {
    // 排序檢測，延伸類別須實作此函數
    // 要讓 O_Key 鍵值所代表的物件排在 左 回答 true，否則 false
    bool cxxlFASTCALL isLeftAt(UNICODE_String O_Key,UNICODE_String addKey) const
    {
      return O_Key <= addKey;
    }

    // 這函數用來決定在容器中 O_Key 鍵值所代表的物件，是不是 findKey 所要尋找的
    // 是 回答 true，否則 false，延伸類別須實作此函數
    bool cxxlFASTCALL isEqual(UNICODE_String O_Key,UNICODE_String findKey)  const
    {
      return O_Key == findKey;
    }

  public:
    DllFileContextTree()  // Constructor
      :cxxlObject(Spirit_Easy)
    {
    }
  }_DllFileContextSet;


  static CriticalSec csObject;

  // Singleton Pattern 的處理部份
  static Smart_Ptr<CentralizedMgr> getInstance1(); // getInstance() 函數指標第一次被叫用時所用的
  static Smart_Ptr<CentralizedMgr> getInstance2(); // getInstance() 函數指標被叫用過後所用的
  static Smart_Ptr<CentralizedMgr> Self; // Singleton 的物件，未初始前指向 NULL，初始後保持到程式姞束



  // 搜尋路徑
  Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > _SearchPath_list;

  // 元件註冊表
  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>, true> > _ElementRegTbl_Composite;

  // 動態元件檔集合
  // Smart_Ptr<DllFileContextTree> _DllFileContextSet_Tree;

  // 檢查 FileName 是不是包含絕對路徑
  virtual bool cxxlFASTCALL isFullPath(const UNICODE_String &FileName) const = 0;

  // 合併路徑和檔名成為完整路徑檔名
  virtual UNICODE_String cxxlFASTCALL Join(const UNICODE_String &PathName, const UNICODE_String &FileName) const = 0;

  // 由延伸類別負責產生 DllFileContext，若 DllFullFile 不存在回覆 NULL
  virtual Smart_Ptr<DllFileContext> cxxlFASTCALL NewDllFileContext(const UNICODE_String &DllFullFile) const = 0;


  // 先向 _DllFileContextSet_Tree 索取，若無再建立一個新的，
  // 失敗(DllFullFile 不存在)回覆 0, 由 _DllFileContextSet_Tree 取得回覆 1, 新建的回覆 2
  int cxxlFASTCALL GetDllFileContext(Smart_Ptr<DllFileContext> &R, const UNICODE_String &DllFullFile) const;

  // 為一個新建立的 cxxlPreserve2 物件處理相關工作
  void cxxlFASTCALL Set_cxxlPreserve2(cxxlPreserve2 *pPreserve2_Arg, const Smart_Ptr<DllFileContext> &DllFileContext_Arg, const UNICODE_String &Group_Arg, const UNICODE_String &ObjID, const UNICODE_String &InterfaceID);

  // 為 Uterus_Ptr 中的每個新生兒呼叫 Set_cxxlPreserve2()
  void cxxlFASTCALL Set_cxxlPreserve2_ForUterus();

  // 為難產的 Uterus_Ptr 中的每個新生兒設定 Spirit
  void cxxlFASTCALL Set_cxxlPreserve2_ForUterusDystocia();

  // 使用再生功能時，用來產生新生兒
  REGENERARETURN_TYPE cxxlFASTCALL NewPreserve2(Smart_Ptr<cxxlPreserve2> &Preserve2_Ret, const UNICODE_String &InterfaceID, const UNICODE_String &ClassID, const UNICODE_String &ObjID, const UNICODE_String &Group, const UNICODE_String &SpiritStr);

protected:


  // Constructor
  CentralizedMgr(ISpirit *spirit)
    :cxxlObject(spirit),
     _SearchPath_list(new cxxlList<string_wrapper<wchar_t> >(Spirit_Urgent),this),
     _ElementRegTbl_Composite(new cxxlComposite<string_wrapper<wchar_t>, true>(L"root",spirit),this)
     // _DllFileContextSet_Tree(new DllFileContextTree(spirit),this)
     // _cxxlPreserve_Tree(new cxxlObject_Tree(spirit),this)
  {
  }

  // Destructor
  virtual ~CentralizedMgr()
  {
  }


public:

/*
  void operator delete(void *,size_t) // 避免被 delete
  {
  }
*/

  // 函數指標，用來建構出 CentralizedMgr 唯一的物件
  static Smart_Ptr<CentralizedMgr> (*getInstance)();

  // 使用再生功能時，用來暫時儲存新生兒
  static Smart_Ptr<Uterus> Uterus_Ptr;


  // 指定搜尋路徑
  void cxxlFASTCALL Init(const Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > &SearchPath_list);

  // 取得搜尋路徑
  Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > cxxlFASTCALL GetSearchPath();


  // 註冊一個元件，若失敗表示 ClassID 已註冊過了
  bool cxxlFASTCALL ElementReg(const UNICODE_String &ClassID, const UNICODE_String &Group, const UNICODE_String &Dll);

  // 從元件註冊庫取得指定元件名稱，若失敗回覆 NULL
  UNICODE_String cxxlFASTCALL ElementGet(const UNICODE_String &ClassID, const UNICODE_String &Group);

  // 查詢 Obj 物件是由哪個元件檔(dll 檔)產件的，含完整路徑。
  // 若 Obj 不是由 cxxlCM_GetElement() 產件的回覆 NULL
  UNICODE_String cxxlFASTCALL Where(const Smart_Ptr<cxxlObject> &Obj);

  // 刪除一個元件的註冊
  void cxxlFASTCALL ElementDel(const UNICODE_String &ClassID, const UNICODE_String &Group);

  // 刪除指定的 Group
  void cxxlFASTCALL ElementDelGroup(const UNICODE_String &Group);

  // 匯入元件註冊表，UUID 不可以重複
  // 若失敗可能是 Group 已存在，或是註冊表不正確
  bool cxxlFASTCALL ElementImport(std::wistream &TLC);

  // 匯入元件註冊表，UUID 不可以重複
  // 若失敗可能是 Group 已存在，或是註冊表不正確
  bool cxxlFASTCALL ElementImport(const Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>,true> > &Reg);


  // 索取一個元件
  // 失敗回傳 NULL
  Smart_Ptr<cxxlObject> cxxlFASTCALL GetElement(
    const UNICODE_String &ClassID,
    const UNICODE_String &Group,
    void *Arg,
    ISpirit *spirit);


  // 再生功能
  REGENERARETURN_TYPE cxxlFASTCALL Regenera(Smart_Ptr<cxxlPreserve2> &P2_Ret,const Smart_Ptr<IPreserve2Storage> &IPreserve2Storage_Arg,bool isRestore);

public:
  // 刪除名稱指定的 DllFileContext
  void cxxlFASTCALL DllFileContextOver(const UNICODE_String &Name)
  {
    _DllFileContextSet.Delete(Name);
  }

  // 刪除名稱指定的 Preserve2Cradle
  void cxxlFASTCALL Preserve2CradleOver(const UNICODE_String &Name)
  {
    _Preserve2CradleSet.Delete(Name);
  }

  // 檢查取得的新 Preserve2 元件，是否符合要求
  bool isMatchingPreserve2(const cxxlPreserve2 *pR, const UNICODE_String &ClassID)
  {
    return pR->ClassID == ClassID;
  }

  friend class DllFileContext;

  friend
  CXXL_DLLEXPORT REGENERARETURN_TYPE cxxlFASTCALL
  CxxlMan::cxxlCM_Regenera(Smart_Ptr<cxxlPreserve2> &P2_Ret, const UNICODE_String &Name, const Smart_Ptr<IcxxlStorage> &IcxxlStorage_Arg, bool isRestore);


};

// 代替 Preserve2 元件放入容器中
class Preserve2Cradle:public cxxlObject
{
  CriticalSec csPreserve2Cradle;
  cxxlPreserve2 *_pPreserve2;
  UNICODE_String _ObjID;
public:
  Preserve2Cradle(cxxlPreserve2 *pPreserve2, const UNICODE_String &ObjID)
    :cxxlObject(Spirit_Easy),
    _ObjID(ObjID)
  {
    _pPreserve2 = pPreserve2;
  }
  ~Preserve2Cradle(){}

  void cxxlFASTCALL LockPreserve2Cradle() const // 給 class YanLuoWang 叫用
  {
    csPreserve2Cradle.Enter();
  }

  void cxxlFASTCALL UnLockPreserve2Cradle() const // 給 class YanLuoWang 叫用
  {
    csPreserve2Cradle.Leave();
  }

  Smart_Ptr<cxxlPreserve2> cxxlFASTCALL Get_Preserve2() const
  {
    CriticalSecHandle AutoCSH(csPreserve2Cradle);
    return _pPreserve2;
  }

  void cxxlFASTCALL ObjOver()
  {
    Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();
    CentralizedMgr_Ptr->Preserve2CradleOver(_ObjID);

    _pPreserve2 = NULL;
    csPreserve2Cradle.Leave();
  }
};

extern CXXLOBJECT_DLLEXPORT ISpirit *Spirit_DllFileContext;   // 非同步處理

// 動態元件檔控管介面
class DllFileContext:public cxxlObject
{
  UNICODE_String _Name; // 以完整路徑的 dll 檔名來命名

protected:
  unsigned long Counter; // 由此產生的物件計數，歸 0 時會自我解構

public:
  DllFileContext(const UNICODE_String &Name)
    :cxxlObject(Spirit_DllFileContext),_Name(Name)
  {
    Counter = 0;
  }
  virtual ~DllFileContext(){}

  virtual cxxlObject *cxxlFASTCALL GetObj(const UNICODE_String &ClassID, void *Arg, ISpirit *spirit) = 0;
  virtual cxxlPreserve2 *cxxlFASTCALL GetPreserve2(const UNICODE_String &ClassID) = 0;

  void cxxlFASTCALL ObjOver()
  {
    CentralizedMgr::csObject.Enter();
    if(--Counter == 0)
    {
      Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();
      // 只有  CentralizedMgr 一個持有者，叫它放棄就會被解構
      CentralizedMgr_Ptr->DllFileContextOver(_Name);
    }
    CentralizedMgr::csObject.Leave();
  }

  friend class CentralizedMgr;
};

// Proxy Patterns
// 實作 ISpirit::ObjOver()
class CSpirit_Surrogate:public ISpirit
{
  ISpirit *_pSpirit;
  DllFileContext *_pDllFileContext;

  virtual void cxxlFASTCALL ToDelete(cxxlObject *Obj) const
  {
    CallToDelete(_pSpirit, Obj);
  }

protected:
  virtual void cxxlFASTCALL ObjOver() const
  {
    _pDllFileContext->ObjOver();
    delete this;
  }

  ISpirit *cxxlFASTCALL GetSpirit() const
  {
    return ISpirit::GetSpirit(_pSpirit);
  }

public:

  // Constructor
  CSpirit_Surrogate(ISpirit *pSpirit, DllFileContext *pDllFileContext)
  {
    _pSpirit = pSpirit;
    _pDllFileContext=pDllFileContext;
  }

  // Destructor
  virtual ~CSpirit_Surrogate()
  {
  }

  DllFileContext *cxxlFASTCALL Get_DllFileContext()
  {
    return _pDllFileContext;
  }

};

// Proxy Patterns
// 實作 ISpirit::ObjOver()
class CSpirit_Preserve2:public CSpirit_Surrogate
{
  Preserve2Cradle *_pPreserve2Cradle;

  virtual void cxxlFASTCALL ObjOver() const
  {
    _pPreserve2Cradle->ObjOver();
    CSpirit_Surrogate::ObjOver();
  }

public:

  // Constructor
  CSpirit_Preserve2(ISpirit *pSpirit, DllFileContext *pDllFileContext, Preserve2Cradle *pPreserve2Cradle)
    :CSpirit_Surrogate(pSpirit, pDllFileContext)
  {
    _pPreserve2Cradle = pPreserve2Cradle;
  }

  // Destructor
  virtual ~CSpirit_Preserve2()
  {
  }

  void cxxlFASTCALL Lock() const
  {
    _pPreserve2Cradle->LockPreserve2Cradle();
  }

  void cxxlFASTCALL UnLock() const
  {
    _pPreserve2Cradle->UnLockPreserve2Cradle();
  }
};


// 延伸自 class IcxxlObject
void cxxlFASTCALL cxxlPreserve2::YanLuoWang_ChkIn()
{
  LockSpirit();
}
void cxxlFASTCALL cxxlPreserve2::YanLuoWang_ChkOut()
{
  UnLockSpirit();
}


// Singleton Pattern 的處理部份
static CentralizedMgr * cxxlFASTCALL CreateCentralizedMgr(); // 由延伸類別實作，new 出自己傳回
CriticalSec CentralizedMgr::csObject;
Smart_Ptr<CentralizedMgr> (*CentralizedMgr::getInstance)() = CentralizedMgr::getInstance1; // 事先定義函數指標指向 getInstance1()

// 使用再生功能時，用來暫時儲存新生兒
Smart_Ptr<Uterus> CentralizedMgr::Uterus_Ptr(NULL);

Smart_Ptr<CentralizedMgr> CentralizedMgr::getInstance1()
{
  CriticalSecHandle AutoCSH(csObject);
  if(Self.isNULL())
  {
    Self = CreateCentralizedMgr(); //new CentralizedMgr;
    getInstance = getInstance2; // 更改函數指標
  }

  return Self;
}

Smart_Ptr<CentralizedMgr> CentralizedMgr::getInstance2()
{
  return Self;
}

Smart_Ptr<CentralizedMgr> CentralizedMgr::Self(NULL);



// 指定搜尋路徑
void cxxlFASTCALL CentralizedMgr::Init(const Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > &SearchPath_list)
{
  csObject.Enter();
  _SearchPath_list = SearchPath_list;
  csObject.Leave();
}

// 取得搜尋路徑
Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > cxxlFASTCALL CentralizedMgr::GetSearchPath()
{
  CriticalSecHandle AutoCSH(csObject);
  return _SearchPath_list;
}


// 註冊一個元件，若失敗表示 ClassID 已註冊過了
bool cxxlFASTCALL CentralizedMgr::ElementReg(const UNICODE_String &ClassID, const UNICODE_String &Group, const UNICODE_String &Dll)
{
  CriticalSecHandle AutoCSH(csObject);
  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>, true> > GroupNode_Ptr = NULL;
  do
  {
    GroupNode_Ptr = _ElementRegTbl_Composite->Add(NULL,Group);
    if(GroupNode_Ptr.isNULL())
      GroupNode_Ptr = _ElementRegTbl_Composite->GetComposite(Group);
  }while(GroupNode_Ptr.isNULL());

  return GroupNode_Ptr->Add(Dll,ClassID).isNULL() != true;
}

// 從元件註冊庫取得指定元件(dll 檔)名稱，若失敗回覆 NULL
UNICODE_String cxxlFASTCALL CentralizedMgr::ElementGet(const UNICODE_String &ClassID, const UNICODE_String &Group)
{
  CriticalSecHandle AutoCSH(csObject);
  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>, true> > GroupNode_Ptr = _ElementRegTbl_Composite->GetComposite(Group);
  if(GroupNode_Ptr.isNULL())
    return (wchar_t *)NULL;

  return (string_wrapper<wchar_t>*)GroupNode_Ptr->GetObj(ClassID);
}

// 查詢 Obj 物件是由哪個元件檔(dll 檔)產件的，含完整路徑。
// 若 Obj 不是由 cxxlCM_GetElement() 產件的回覆 NULL
UNICODE_String cxxlFASTCALL CentralizedMgr::Where(const Smart_Ptr<cxxlObject> &Obj)
{
  ISpirit *pISpirit = ICentralizedMgr::GetSpiritSelf(Obj);

  CSpirit_Surrogate *pCSpirit_Surrogate = dynamic_cast<CSpirit_Surrogate *>(pISpirit);
  if(pCSpirit_Surrogate)
  {
    return pCSpirit_Surrogate->Get_DllFileContext()->_Name;
  }

  return UNICODE_String();
}

// 刪除一個元件的註冊
void cxxlFASTCALL CentralizedMgr::ElementDel(const UNICODE_String &ClassID, const UNICODE_String &Group)
{
  csObject.Enter();
  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>, true> > GroupNode_Ptr = _ElementRegTbl_Composite->GetComposite(Group);

  if(GroupNode_Ptr.isNULL() == false)
    GroupNode_Ptr->Delete(GroupNode_Ptr->GetComposite(ClassID));

  csObject.Leave();
}

// 刪除指定的 Group
void cxxlFASTCALL CentralizedMgr::ElementDelGroup(const UNICODE_String &Group)
{
  csObject.Enter();
  _ElementRegTbl_Composite->Delete(_ElementRegTbl_Composite->GetComposite(Group));
  csObject.Leave();
}

// 匯入元件註冊表，UUID 若存在不會覆寫
// 若失敗表示註冊表不正確
bool cxxlFASTCALL CentralizedMgr::ElementImport(std::wistream &TLC)
{
  CriticalSecHandle AutoCSH(csObject);

  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>,true> > tmp = UniqueTxtCompositeImport(TLC);

  return ElementImport(tmp);
}

// 匯入元件註冊表，UUID 不可以重複
bool cxxlFASTCALL CentralizedMgr::ElementImport(const Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>,true> > &Reg)
{
  if(Reg.isNULL())
    return false;

  UNICODE_String GroupName = Reg->GetName();
  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>,true> > Dest = _ElementRegTbl_Composite->Add(NULL,GroupName);

  if(Dest.isNULL())
    Dest = _ElementRegTbl_Composite->GetComposite(GroupName);

  Smart_Ptr<cxxlList<cxxlComposite<string_wrapper<wchar_t>, true> > > Composite_List = Reg->cxxlList_Create();
  Composite_List->ResetPT(toHead);
  for( Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>,true> > Src = (*Composite_List)++;
         Src.isNULL() != true; Src = (*Composite_List)++ )
  {
    Dest->Add(Src->GetObj(),Src->GetName());
  }

  return true;
}


// 索取一個元件
// 失敗回傳 NULL
Smart_Ptr<cxxlObject> cxxlFASTCALL CentralizedMgr::GetElement(
  const UNICODE_String &ClassID,
  const UNICODE_String &Group,
  void *Arg,
  ISpirit *spirit)
{
  CriticalSecHandle AutoCSH(csObject);

  Smart_Ptr<cxxlList<cxxlComposite<string_wrapper<wchar_t>, true> > > ElementRegTbl_List(NULL);

  if(Group.isNULL())
    ElementRegTbl_List = _ElementRegTbl_Composite->cxxlList_Create();
  else
  {
    ElementRegTbl_List = new cxxlList<cxxlComposite<string_wrapper<wchar_t>, true> >;
    ElementRegTbl_List->Push_Back(_ElementRegTbl_Composite->GetComposite(Group));
  }

  ElementRegTbl_List->ResetPT(toHead);


  for(Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>, true > > GroupNode_Ptr = (*ElementRegTbl_List)++;
    GroupNode_Ptr.isNULL() == false;
    GroupNode_Ptr = (*ElementRegTbl_List)++)
  {
    UNICODE_String DllFile( GroupNode_Ptr->GetObj(ClassID) ); // 取得檔名
    if(DllFile.isNULL())
      continue;

    if(isFullPath(DllFile)) // 已是完整路徑檔名
    {
      Smart_Ptr<DllFileContext> DllFileContext_Ptr(NULL);
      int I_Flag  = GetDllFileContext(DllFileContext_Ptr, DllFile);
      if(I_Flag == 0)
        return NULL;

      if(I_Flag == 2) // 新建
        _DllFileContextSet.Add(DllFileContext_Ptr,DllFile); // 先加入

      cxxlObject *pR = DllFileContext_Ptr->GetObj(ClassID, Arg, spirit);
      if(pR == NULL)
      {
        if(I_Flag == 2 && DllFileContext_Ptr->Counter == 0) // 若是新建
          _DllFileContextSet.Delete(DllFile); // 刪掉

        return NULL;
      }


      cxxlPreserve2 *pPreserve2 = (cxxlPreserve2 *)ICentralizedMgr::GetPreserve2(pR);
      if(pPreserve2 != NULL)
        Set_cxxlPreserve2(pPreserve2, DllFileContext_Ptr, GroupNode_Ptr->GetName(), CreateGuidWStr(), ClassID);
      else // 不是 cxxlPreserve2
        ICentralizedMgr::SetSpirit(pR, new CSpirit_Surrogate(ICentralizedMgr::GetSpirit(pR),DllFileContext_Ptr) );

      return pR;
    }
    else
    {
      _SearchPath_list->ResetPT(toHead);
      for(UNICODE_String Path( (*_SearchPath_list)++ );
        Path.isNULL() == false;
        Path = (*_SearchPath_list)++)
      {
        UNICODE_String FullDllFileName = Join(Path, DllFile);

        Smart_Ptr<DllFileContext> DllFileContext_Ptr(NULL);
        int I_Flag = GetDllFileContext(DllFileContext_Ptr, FullDllFileName);
        if(I_Flag == 0)
          continue;

        if(I_Flag == 2) // 新建
          _DllFileContextSet.Add(DllFileContext_Ptr,FullDllFileName); // 先加入

        cxxlObject *pR = DllFileContext_Ptr->GetObj(ClassID, Arg, spirit);
        if(pR == NULL)
        {
          if(I_Flag == 2 && DllFileContext_Ptr->Counter == 0) // 若是新建
            _DllFileContextSet.Delete(FullDllFileName); // 刪掉

          continue;
        }


        cxxlPreserve2 *pPreserve2 = (cxxlPreserve2 *)ICentralizedMgr::GetPreserve2(pR);
        if(pPreserve2 != NULL)
          Set_cxxlPreserve2(pPreserve2, DllFileContext_Ptr, GroupNode_Ptr->GetName(), CreateGuidWStr(), ClassID);
        else // 不是 cxxlPreserve2
          ICentralizedMgr::SetSpirit(pR, new CSpirit_Surrogate(ICentralizedMgr::GetSpirit(pR),DllFileContext_Ptr) );

        return pR;
      }
      return NULL;
    }
  }
  return NULL;
}

// 為一個新建立的 cxxlPreserve2 物件處理相關工作
void cxxlFASTCALL CentralizedMgr::Set_cxxlPreserve2(cxxlPreserve2 *pPreserve2_Arg, const Smart_Ptr<DllFileContext> &DllFileContext_Arg, const UNICODE_String &Group_Arg, const UNICODE_String &ObjID_Arg, const UNICODE_String &InterfaceID_Arg)
{
  // UNICODE_String ObjID(CreateGuidWStr());
  Preserve2Cradle *pPreserve2Cradle = new Preserve2Cradle(pPreserve2_Arg, ObjID_Arg);
  _Preserve2CradleSet.Add(pPreserve2Cradle, ObjID_Arg);

  ICentralizedMgr::SetSpirit(pPreserve2_Arg, new CSpirit_Preserve2(ICentralizedMgr::GetSpirit(pPreserve2_Arg),DllFileContext_Arg, pPreserve2Cradle));
  pPreserve2_Arg->SetInterfaceID(InterfaceID_Arg);
  pPreserve2_Arg->SetObjID(ObjID_Arg);
  pPreserve2_Arg->SetGroup(Group_Arg);
}

// 為 Uterus_Ptr 中的每個新生兒呼叫 Set_cxxlPreserve2()
void cxxlFASTCALL CentralizedMgr::Set_cxxlPreserve2_ForUterus()
{
  Smart_Ptr<cxxlList<Preserve2Baby> > Preserve2Baby_List = Uterus_Ptr->Get_Preserve2Baby_List();

  Preserve2Baby_List->ResetPT(toHead);
  for(Smart_Ptr<Preserve2Baby> Preserve2Baby_Ptr = (*Preserve2Baby_List)++;
    Preserve2Baby_Ptr.isNULL() == false;
    Preserve2Baby_Ptr = (*Preserve2Baby_List)++)
  {
    Set_cxxlPreserve2(Preserve2Baby_Ptr->Preserve2_Ptr, Preserve2Baby_Ptr->DllFileContext_Ptr, Preserve2Baby_Ptr->Group, Preserve2Baby_Ptr->ObjID, Preserve2Baby_Ptr->InterfaceID);
  }
}

// 為難產的 Uterus_Ptr 中的每個新生兒設定 Spirit
void cxxlFASTCALL CentralizedMgr::Set_cxxlPreserve2_ForUterusDystocia()
{
  Smart_Ptr<cxxlList<Preserve2Baby> > Preserve2Baby_List = Uterus_Ptr->Get_Preserve2Baby_List();

  Preserve2Baby_List->ResetPT(toHead);
  for(Smart_Ptr<Preserve2Baby> Preserve2Baby_Ptr = (*Preserve2Baby_List)++;
    Preserve2Baby_Ptr.isNULL() == false;
    Preserve2Baby_Ptr = (*Preserve2Baby_List)++)
  {
    ICentralizedMgr::SetSpirit(Preserve2Baby_Ptr->Preserve2_Ptr, new CSpirit_Surrogate(ICentralizedMgr::GetSpirit(Preserve2Baby_Ptr->Preserve2_Ptr),Preserve2Baby_Ptr->DllFileContext_Ptr) );
  }
}

// 先向 _DllFileContextSet_Tree 索取，若無再建立一個新的，
// 失敗(DllFullFile 不存在)回覆 0, 由 _DllFileContextSet_Tree 取得回覆 1, 新建的回覆 2
int cxxlFASTCALL CentralizedMgr::GetDllFileContext(Smart_Ptr<DllFileContext> &R, const UNICODE_String &DllFullFile) const
{
  R = _DllFileContextSet.GetObj(DllFullFile);
  if(R.isNULL())
  {
    R = NewDllFileContext(DllFullFile);
    if(R.isNULL())
      return 0;
    else
      return 2;
  }
  return 1;
}

// 以遞迴方式再生每一個 cxxlPreserve2 節點
REGENERARETURN_TYPE cxxlFASTCALL CentralizedMgr::Regenera(Smart_Ptr<cxxlPreserve2> &P2_Ret,const Smart_Ptr<IPreserve2Storage> &IPreserve2Storage_Arg,bool isRestore)
{
  if(IPreserve2Storage_Arg->isEmpty())
    return Regenera_Empty;  

  UNICODE_String ObjID = IPreserve2Storage_Arg->GetObjID();
  if(ObjID.isNULL() == false)
  {
    Smart_Ptr<Preserve2Cradle> Preserve2Cradle_Ptr = _Preserve2CradleSet.GetObj(ObjID);
    if(Preserve2Cradle_Ptr.isNULL() == false)
    {
      P2_Ret = Preserve2Cradle_Ptr->Get_Preserve2();
      if(P2_Ret.isNULL() == false)
        return Regenera_Success;
    }

    Smart_Ptr<Preserve2Baby> Preserve2Baby_Ptr = Uterus_Ptr->Get(ObjID);
    if(Preserve2Baby_Ptr.isNULL() == false)
    {
      P2_Ret = Preserve2Baby_Ptr->Preserve2_Ptr;
      return Regenera_Success;
    }
  }
  else
    ObjID = CreateGuidWStr();

  UNICODE_String InterfaceID = IPreserve2Storage_Arg->GetInterfaceID();
  if(InterfaceID.isNULL()) // 不是 cxxlPreserve2 的永存節點
  {
    return Regenera_NotPreserve2;
  }

  UNICODE_String ClassID = IPreserve2Storage_Arg->GetClassID();
  if(ClassID.isNULL()) // 不是 cxxlPreserve2 的永存節點
  {
    return Regenera_NotPreserve2;
  }

  UNICODE_String SpiritStr = IPreserve2Storage_Arg->GetSpiritStr();
  if(SpiritStr.isNULL()) // 不是 cxxlPreserve2 的永存節點
  {
    return Regenera_NotPreserve2;
  }

  UNICODE_String GroupStr = IPreserve2Storage_Arg->GetGroup();
  if(GroupStr.isNULL()) // 不是 cxxlPreserve2 的永存節點
  {
    return Regenera_NotPreserve2;
  }

  REGENERARETURN_TYPE RT = NewPreserve2(P2_Ret, InterfaceID, ClassID, ObjID, GroupStr, SpiritStr);
  if(RT != Regenera_Success)
    return RT;

  cxxlPreserve *pPreserve = (cxxlPreserve2 *)P2_Ret;

  _Sets *p = pPreserve->_Sets_List;
  IPreserve2Storage_Arg->ResetFirst();

  while(true)
  {
    if(p != NULL && IPreserve2Storage_Arg->haveSetCount())
    {
      unsigned long SetCount = IPreserve2Storage_Arg->GetSetCount();
      for(unsigned long i = 0; i < SetCount; ++i)
      {
        Smart_Ptr<IPreserve2Storage> SubIPreserve2Storage_Ptr = IPreserve2Storage_Arg->GetIPreserve2StorageNext();
        if(p->GetName() != SubIPreserve2Storage_Ptr->GetName())
        {
          return Regenera_NotSamePSmart_PtrName;
        }

        Smart_Ptr<cxxlPreserve2> P2tmp_Ptr(NULL);
        RT = Regenera(P2tmp_Ptr,SubIPreserve2Storage_Ptr,isRestore);


        if(RT != Regenera_Success)
        {
          if(RT == Regenera_Empty)
          {
            RT = p->PutEmptyPreserve2();
            if(RT != Regenera_Success)
              return RT;            
          }
          else if(RT == Regenera_NotPreserve2)
          {
            if(isRestore)
            {
              Smart_Ptr<cxxlList<cxxlPreserve> > cxxlPreserveSet_List = p->GetPreserveList();
              cxxlPreserveSet_List->ResetPT(toHead);

              if(SetCount != cxxlPreserveSet_List->GetCount())
                return Regenera_RestoreError;

              Smart_Ptr<cxxlPreserve> cxxlPreserve_Ptr = (*cxxlPreserveSet_List)++;
              if(cxxlPreserve_Ptr.isNULL() == false)
                if(SubIPreserve2Storage_Ptr->Load(cxxlPreserve_Ptr) == false)
                  return Regenera_RestoreError;
            }
          }
          else
          {
            return RT;
          }
        }
        else // if(RT == Regenera_Success)
        {
          RT = p->PutPreserve2(P2tmp_Ptr);
          if(RT != Regenera_Success)
          {
            return RT;
          }
        }
      }     
    }
    else if(p == NULL && IPreserve2Storage_Arg->haveSetCount() == false)
    {
      break;
    }
    else
    {
      return Regenera_NotSameP2Smart_Ptr;
    }
    p = p->Next;    
  }

  if(isRestore)
  {
    if(!IPreserve2Storage_Arg->Load((cxxlPreserve*)P2_Ret))
    {
      P2_Ret.Destroy();
      return Regenera_RestoreError;
    }
  }

  return Regenera_Success;
}

REGENERARETURN_TYPE cxxlFASTCALL CentralizedMgr::NewPreserve2(
  Smart_Ptr<cxxlPreserve2> &Preserve2_Ret,
  const UNICODE_String &InterfaceID,
  const UNICODE_String &ClassID,
  const UNICODE_String &ObjID,
  const UNICODE_String &Group,
  const UNICODE_String &SpiritStr)
{

  Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>, true > > GroupNode_Ptr = _ElementRegTbl_Composite->GetComposite(Group);
  if(GroupNode_Ptr.isNULL())
    return Regenera_NotRegistered;

  UNICODE_String DllFile( GroupNode_Ptr->GetObj(InterfaceID) ); // 取得檔名
  if(DllFile.isNULL())
    return Regenera_NotRegistered;

  if(isFullPath(DllFile)) // 已是完整路徑檔名
  {
    Smart_Ptr<DllFileContext> DllFileContext_Ptr(NULL);
    int I_Flag  = GetDllFileContext(DllFileContext_Ptr, DllFile);
    if(I_Flag == 0)
      return Regenera_NotGetPreserve2;

    if(I_Flag == 2) // 新建
      _DllFileContextSet.Add(DllFileContext_Ptr,DllFile); // 先加入

    Preserve2_Ret = DllFileContext_Ptr->GetPreserve2(ClassID);
    if(Preserve2_Ret.isNULL())
    {
      if(I_Flag == 2 && DllFileContext_Ptr->Counter == 0) // 若是新建
        _DllFileContextSet.Delete(DllFile); // 刪掉

      return Regenera_NotGetPreserve2;
    }


    if(SpiritStr == L"Spirit_Urgent")
      ICentralizedMgr::SetSpirit(Preserve2_Ret,Spirit_Urgent);
    else
      ICentralizedMgr::SetSpirit(Preserve2_Ret,Spirit_Easy);

    Uterus_Ptr->Add(new Preserve2Baby(InterfaceID, ObjID, Group, Preserve2_Ret, DllFileContext_Ptr), ObjID);
    return Regenera_Success;
  }
  else
  {
    _SearchPath_list->ResetPT(toHead);
    for(UNICODE_String Path( (*_SearchPath_list)++ );
      Path.isNULL() == false;
      Path = (*_SearchPath_list)++)
    {
      UNICODE_String FullDllFileName = Join(Path, DllFile);

      Smart_Ptr<DllFileContext> DllFileContext_Ptr(NULL);
      int I_Flag = GetDllFileContext(DllFileContext_Ptr, FullDllFileName);
      if(I_Flag == 0)
        continue;

      if(I_Flag == 2) // 新建
        _DllFileContextSet.Add(DllFileContext_Ptr,FullDllFileName); // 先加入

      Preserve2_Ret = DllFileContext_Ptr->GetPreserve2(ClassID);
      if(Preserve2_Ret.isNULL())
      {
        if(I_Flag == 2 && DllFileContext_Ptr->Counter == 0) // 若是新建
          _DllFileContextSet.Delete(FullDllFileName); // 刪掉

        continue;
      }

      if(SpiritStr == L"Spirit_Urgent")
        ICentralizedMgr::SetSpirit(Preserve2_Ret,Spirit_Urgent);
      else
        ICentralizedMgr::SetSpirit(Preserve2_Ret,Spirit_Easy);

      Uterus_Ptr->Add(new Preserve2Baby(InterfaceID, ObjID, Group, Preserve2_Ret, DllFileContext_Ptr), ObjID);
      return Regenera_Success;
    }
    return Regenera_NotGetPreserve2;
  }

}

/*--------------------
 Win32
--------------------*/

#if (SysSelect == _WIN32_CxxlMan)

#include <windows.h>

class DllFileContext_WIN32:public DllFileContext
{

  HINSTANCE DLLInst;
  cxxlObject* (* cxxlCDECL pObjectFactory)( const wchar_t *ClassID, void *Arg, ISpirit *spirit);
  cxxlPreserve2* (* cxxlCDECL pPreserve2Factory)( const wchar_t *ClassID);


  virtual cxxlObject *cxxlFASTCALL GetObj(const UNICODE_String &ClassID, void *Arg, ISpirit *spirit)
  {
    cxxlObject *pR = pObjectFactory(ClassID, Arg, spirit);
    if(pR != NULL)
      ++Counter;
    return pR;
  }

  virtual cxxlPreserve2 *cxxlFASTCALL GetPreserve2(const UNICODE_String &ClassID)
  {
    if(pPreserve2Factory == NULL)
      return NULL;

    cxxlPreserve2 *pR = pPreserve2Factory(ClassID);

    if(pR == NULL)
    {
      return NULL;
    }
    else
    {
      Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();
      if(CentralizedMgr_Ptr->isMatchingPreserve2(pR,ClassID))
      {
        ++Counter;
        return pR;
      }
      else
      {
        delete pR;
        return NULL;
      }
    }
  }

public:

  // Constructor
  DllFileContext_WIN32(const UNICODE_String &DllFullFile, ISpirit *spirit)
    :DllFileContext(DllFullFile)
  {
    DLLInst = LoadLibraryW(DllFullFile);
    if(DLLInst != NULL)
    {
      pObjectFactory = ( cxxlObject* (cxxlCDECL *)(const wchar_t *ClassID, void *Arg, ISpirit *spirit) )
        GetProcAddress(DLLInst, "CxxlMan_ObjectFactory");

      if(pObjectFactory == NULL)
        FreeLibrary(DLLInst);

      pPreserve2Factory = ( cxxlPreserve2* (cxxlCDECL *)(const wchar_t *ClassID) )GetProcAddress(DLLInst, "CxxlMan_Preserve2Factory");

    }
    else
      pObjectFactory = NULL;

  }

  // Dwstructor
  virtual ~DllFileContext_WIN32()
  {
    if(DLLInst != NULL)
      FreeLibrary(DLLInst);
  }

  bool cxxlFASTCALL isOK() const
  {
    return pObjectFactory != NULL;
  }
};


class CentralizedMgr_WIN32:public CentralizedMgr
{

  // 檢查 FileName 是不是包含絕對路徑
  virtual bool cxxlFASTCALL isFullPath(const UNICODE_String &FileName) const
  {
    // if( FileName[1] == L':' || FileName[0] == L'\\')
    const wchar_t *S = FileName;
    if( S[1] == L':' || S[0] == L'\\')
      return true;
    else
      return false;
  }

  // 產生 DllFileContext，若 DllFullFile 不存在回覆 NULL
  Smart_Ptr<DllFileContext> cxxlFASTCALL NewDllFileContext(const UNICODE_String &DllFullFile) const
  {
    DllFileContext_WIN32 *R = new DllFileContext_WIN32(DllFullFile, Spirit_Easy);
    if(R->isOK())
      return R;

    delete R;
    return NULL;
  }

  // 合併路徑和檔名成為完整路徑檔名
  UNICODE_String cxxlFASTCALL Join(const UNICODE_String &PathName, const UNICODE_String &FileName) const
  {
    if(PathName[PathName.StrLength() - 1] == L'\\')
      return PathName + FileName;
    else
      return PathName + L"\\" +FileName;
  }

  // Constructor
  CentralizedMgr_WIN32(ISpirit *spirit = Spirit_Easy)
    :cxxlObject(spirit),
    CentralizedMgr(spirit)
  {

  }

  // Destructor
  virtual ~CentralizedMgr_WIN32()
  {
  }



public:


  friend CentralizedMgr * cxxlFASTCALL CreateCentralizedMgr();
};

static CentralizedMgr * cxxlFASTCALL CreateCentralizedMgr()
{
  return new CentralizedMgr_WIN32;
}

#else
  #error 尚未支援此作業系統
#endif



// 指定搜尋路徑
CXXL_DLLEXPORT void cxxlFASTCALL CxxlMan::cxxlCM_Init(const Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > &SearchPath_list)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  CentralizedMgr_Ptr->Init(SearchPath_list);
}


// 取得搜尋路徑
CXXL_DLLEXPORT Smart_Ptr<cxxlList<string_wrapper<wchar_t> > > cxxlFASTCALL CxxlMan::cxxlCM_GetSearchPath()
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->GetSearchPath();
}

// 註冊一個元件，若失敗表示 ClassID 已註冊過了
CXXL_DLLEXPORT bool cxxlFASTCALL CxxlMan::cxxlCM_ElementReg(const UNICODE_String &ClassID, const UNICODE_String &Group, const UNICODE_String &Dll)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->ElementReg(ClassID, Group, Dll);
}

// 從元件註冊庫取得指定元件名稱，若失敗回覆 NULL
CXXL_DLLEXPORT UNICODE_String cxxlFASTCALL CxxlMan::cxxlCM_ElementGet(const UNICODE_String &ClassID, const UNICODE_String &Group)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->ElementGet(ClassID, Group);
}

// 查詢 Obj 物件是由哪個元件檔(dll 檔)產件的，含完整路徑。
// 若 Obj 不是由 cxxlCM_GetElement() 產件的回覆 NULL
CXXL_DLLEXPORT UNICODE_String cxxlFASTCALL CxxlMan::cxxlCM_Where(const Smart_Ptr<cxxlObject> &Obj)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->Where(Obj);
}


// 刪除一個元件的註冊
CXXL_DLLEXPORT void cxxlFASTCALL CxxlMan::cxxlCM_ElementDel(const UNICODE_String &ClassID, const UNICODE_String &Group)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  CentralizedMgr_Ptr->ElementDel(Group, ClassID);
}

// 刪除指定的 Group
CXXL_DLLEXPORT void cxxlFASTCALL CxxlMan::cxxlCM_ElementDelGroup(const UNICODE_String &Group)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  CentralizedMgr_Ptr->ElementDelGroup(Group);
}

// 匯入元件註冊表，UUID 不可以重複
// 若失敗表示註冊表不正確
CXXL_DLLEXPORT bool cxxlFASTCALL CxxlMan::cxxlCM_ElementImport(std::wistream &TLC)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->ElementImport(TLC);
}

// 匯入元件註冊表，UUID 若存在不會覆寫
// 若失敗表示註冊表不正確
CXXL_DLLEXPORT bool cxxlFASTCALL CxxlMan::cxxlCM_ElementImport(const Smart_Ptr<cxxlComposite<string_wrapper<wchar_t>,true> > &Reg)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->ElementImport(Reg);
}


// 索取一個元件
// 失敗回傳 NULL
CXXL_DLLEXPORT Smart_Ptr<cxxlObject> cxxlFASTCALL CxxlMan::cxxlCM_GetElement(
  const UNICODE_String &ClassID,
  const UNICODE_String &Group,
  void *Arg,
  ISpirit *spirit)
{
  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  return CentralizedMgr_Ptr->GetElement(ClassID, Group, Arg, spirit);
}


CXXL_DLLEXPORT REGENERARETURN_TYPE cxxlFASTCALL
CxxlMan::cxxlCM_Regenera(Smart_Ptr<cxxlPreserve2> &P2_Ret, const UNICODE_String &Name, const Smart_Ptr<IcxxlStorage> &IcxxlStorage_Arg, bool isRestore)
{
  Smart_Ptr<IPreserve2Storage> IPreserve2Storage_Ptr = IcxxlStorage_Arg->GetIPreserve2Storage(Name);
  if(IPreserve2Storage_Ptr.isNULL())
    return Regenera_NoName;

  Smart_Ptr<CentralizedMgr> CentralizedMgr_Ptr = CentralizedMgr::getInstance();

  CriticalSecHandle AutoCSH(CentralizedMgr::csObject);

  static unsigned int Counter = 0; // 記錄在同一個執行緒重複進入 cxxlCM_Regenera() 的次數
  if(++Counter == 1)
    CentralizedMgr::Uterus_Ptr = new Uterus;

  REGENERARETURN_TYPE RH = CentralizedMgr_Ptr->Regenera(P2_Ret, IPreserve2Storage_Ptr, isRestore);

  if(RH == Regenera_Success)
    CentralizedMgr_Ptr->Set_cxxlPreserve2_ForUterus();
  else
    CentralizedMgr_Ptr->Set_cxxlPreserve2_ForUterusDystocia();


  if(--Counter == 0)
    CentralizedMgr::Uterus_Ptr.Destroy();

  return RH;
}

// 定義在 txtstorage.cpp
extern bool cxxlFASTCALL CutPreserve2(const Smart_Ptr<TxtStorage> &TxtStorage_Arg, bool ClearObjID, bool DelRestore);
extern bool cxxlFASTCALL CutPreserve2(const Smart_Ptr<TxtStorage> &TxtStorage_Arg, const UNICODE_String &Name, bool ClearObjID, bool DelRestore);

// 定義在 memstorage.cpp
extern bool cxxlFASTCALL CutPreserve2(const Smart_Ptr<MemStorage> &MemStorage_Arg, bool ClearObjID, bool DelRestore);
extern bool cxxlFASTCALL CutPreserve2(const Smart_Ptr<MemStorage> &MemStorage_Arg, const UNICODE_String &Name, bool ClearObjID, bool DelRestore);


// 切斷 IcxxlStorage_Arg 中，所有 cxxlPreserve2 永存資料的共用物件資訊，即讓 ObjID 資訊失去作用
CXXL_DLLEXPORT bool cxxlFASTCALL CxxlMan::cxxlCM_CutPreserve2(const Smart_Ptr<IcxxlStorage> &IcxxlStorage_Arg, bool ClearObjID, bool DelRestore)
{

  Smart_Ptr<TxtStorage> TxtStorage_Ptr = Smart_Cast<TxtStorage>(IcxxlStorage_Arg);
  if(TxtStorage_Ptr.isNULL())
    return CutPreserve2(Smart_Cast<MemStorage>(IcxxlStorage_Arg), ClearObjID, DelRestore);
  else
    return CutPreserve2(TxtStorage_Ptr, ClearObjID, DelRestore);

}

// 切斷 IcxxlStorage_Arg 中，指定名稱的 cxxlPreserve2 永存資料的共用物件資訊，即讓 ObjID 資訊失去作用
CXXL_DLLEXPORT bool cxxlFASTCALL cxxlCM_CutPreserve2(const Smart_Ptr<IcxxlStorage> &IcxxlStorage_Arg, const UNICODE_String &Name, bool ClearObjID, bool DelRestore)
{

  Smart_Ptr<TxtStorage> TxtStorage_Ptr = Smart_Cast<TxtStorage>(IcxxlStorage_Arg);
  if(TxtStorage_Ptr.isNULL())
    return CutPreserve2(Smart_Cast<MemStorage>(IcxxlStorage_Arg), Name, ClearObjID, DelRestore);
  else
    return CutPreserve2(TxtStorage_Ptr, Name, ClearObjID, DelRestore);
}

